import org.junit.jupiter.api.Test;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 多线程的实现方式
 *
 * @author 阳秋豪
 * @createTime 2024/3/11
 */
public class Test2 {
    /*----- 继承 Thread 类的方式进行实现 -----*/
    @Test
    public void test1() {
        // 1.自己定义一个类继承 Thread
        // 2.重写run方法
        // 3.创建子类的对象
        MyThread1 t1 = new MyThread1();
        MyThread1 t2 = new MyThread1();
        // 给线程起名字
        // -- 有默认名字 Thread-序号 ，序号是创建对象的顺序从零开始
        t1.setName("线程1");
        t2.setName("线程2");
        // 4.启动线程
        t1.start();
        t2.start();
    }

    /*----- 实现 Runnable 接口的方式进行实现 -----*/
    @Test
    public void test2() {
        // 1.自己定义一个类实现 Runnable 接口
        // 2.重写run方法
        // 3.创建子类的对象
        MyThread2 myThread = new MyThread2();
        // 4.创建一个 Thread 类对象
        Thread t1 = new Thread(myThread);
        Thread t2 = new Thread(myThread);
        // 给线程起名字
        // -- 不取名有默认名字 Thread-序号 ，序号是创建对象的顺序从零开始
        // -- Thread 类中的方法 Runnable 中没有（可以通过 Thread.currentThread()方法获取当前线程对象）
        t1.setName("线程1");
        t2.setName("线程2");
        // 5.并启动线程
        t1.start();
        t2.start();
    }

    /*----- 利用 Callable 接口和 Future 接口实现 -----*/
    @Test
    public void test3() {
        // 特点：可以获取多线程的运行结果
        // 1.创建一个类实现 Callable 接口
        // 2.重写 call 方法 (是有返回值的，表示多线程运行的结果)
        // 3.创建实现 Callable 接口类的对象 (表示多线程要执行的任务)
        MyThread3 myThread = new MyThread3();
        // 4.创建 FutureTask 的对象 (作用管理多线程运行的结果)
        FutureTask<Integer> future = new FutureTask<>(myThread);
        // 5.创建 Thread 类的对象
        Thread t1 = new Thread(future);
        // 6.启动(表示线程)
        t1.start();
        // 7.获取线程运行结果
        Integer sum = null;
        try {
            sum = future.get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
        System.out.println("和 -- " + sum);
    }


}

class MyThread1 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName() + " -- 第一种多线程启动方式");
        }
    }
}

class MyThread2 implements Runnable {
    @Override
    public void run() {
        // 获取到当前线程对象
        Thread currentThread = Thread.currentThread();
        for (int i = 0; i < 10; i++) {
            System.out.println(currentThread.getName() + " -- 第二种多线程启动方式");
        }
    }
}

class MyThread3 implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        // 求 1 ~ 100 的和
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            sum += i;
        }
        return sum;
    }
}